<?php
/**
 * CreateUser: zlh
 * CreateTime: 2022/1/26 10:32
 * Remark:
 */

namespace App\Http\Middleware\Staff;

use App\Consts\BaseConsts\BaseConsts;
use App\Consts\RequestConsts\RequestMethodConsts;
use App\Consts\ResponseConsts\ResponseStatusConsts;
use App\Func\ResponseFunc;
use App\Func\TokenFuc;
use App\Models\Auth\AuthBasicModel;
use App\Models\Auth\AuthMenuModel;
use App\Models\Company\CompanyModel;
use App\Models\Department\DepartmentModel;
use App\Models\Position\PositionModel;
use App\Models\Staff\StaffDepartmentModel;
use App\Models\Staff\StaffModel;
use Closure;
use Illuminate\Http\Exceptions\HttpResponseException;

class StaffLegitimacyMiddleware
{
    private PositionModel $_positionModel;
    private DepartmentModel $_departmentModel;
    private CompanyModel $_companyModel;
    private StaffModel $_staffModel;
    private StaffDepartmentModel $_staffDepartmentModel;
    private AuthMenuModel $_authMenuModel;
    private AuthBasicModel $_authModel;

    public function __construct()
    {
        $this->_staffModel = new StaffModel();
        $this->_positionModel = new PositionModel();
        $this->_departmentModel = new DepartmentModel();
        $this->_companyModel = new CompanyModel();
        $this->_staffDepartmentModel = new StaffDepartmentModel();
        $this->_authMenuModel = new AuthMenuModel();
        $this->_authModel = new AuthBasicModel();
    }

    public function handle($request, Closure $next)
    {
        $method = strtolower($request->method());
        switch ($method){
            case RequestMethodConsts::GET_METHOD:
                //
                break;
            case RequestMethodConsts::POST_METHOD:
                // 授权判断
                if($request['auths']){
                    $this->verifyStaffIsExist($request['staff_id']);
                    // 校验当前权限是合法
                    $this->verifyAuthBasic($request['auths']);
                }
                if($request['company_id'] && $request['staff_login_account']){
                    // 验证登录账号是否存在
                    $this->verifyLoginAccountIsExist($request['company_id'], $request['staff_login_account']);
                    // 新增时校验 公司是否存在
                    $this->verifyCompanyIsExist($request['company_id']);
                    if($request['departments']){
                        // 新增时校验 部门和职位是否匹配
                        $departments = $request['departments'];
                        // 校验部门是否存在 且 当前职位是否存在
                        $departmentIds = [];
                        foreach($departments as $department){
                            if(isset($departmentIds[$department['department_id']])){
                                throw new HttpResponseException( ResponseFunc::returnJson(
                                    'error',
                                    null,
                                    '用户在当前部门已存在',
                                    ResponseStatusConsts::OK_200_RESPONSE_STATUS,

                                ));
                            }
                            $departmentIds[$department['department_id']] = 1;
                            // 校验部门 职位是否存在
                            $this->verifyDepartmentIsExist($request['company_id'],$department['department_id']);
                            $this->verifyPositionIsExist($department['department_id'],$department['position_id']);
                        }
                     }
                }
                break;
            case RequestMethodConsts::PUT_METHOD:
                if($request['departments']){
                    // 新增时校验 部门和职位是否匹配
                    $departments = $request['departments'];
                    // 校验
                    $departmentId = $departments['department_id'];
                    $positionId = $departments['position_id'];
                    // 校验当前公司下部门是否存在
                    $companyId = TokenFuc::getCurrentStaffInfo()['company_id'] ?? 0;
                    $this->verifyDepartmentIsExist($companyId,$departmentId);
                    $this->verifyPositionIsExist($departmentId,$positionId);
                    // 新增职位时判断当前用户是否已经存在这个部门
                    $this->verifyStaffDepartmentHasStaffIsExist($request->staffId,$departmentId);
                }
                //修改部门职位时
                if($request->staffId && $request->staffDepartmentId){
                    // 校验部门id是否存在
                    $this->verifyStaffDepartmentIsExist($request->staffId,$request->staffDepartmentId);
                }
                break;
            case RequestMethodConsts::PATCH_METHOD:
                // 删除员工时 验证员工是否存在
                if($request->staffId){
                    $this->verifyStaffIsExist($request->staffId);
                }
                // 校验当前员工部门是否匹配
                if($request->staffId && $request->staffDepartmentId){
                    $this->verifyStaffDepartmentIsExist($request->staffId,$request->staffDepartmentId);
                }
                // 停用用户时校验 当前用户是否为启用状态
                if($request->stopStaffId){
                    $this->verifyStaffIsExist($request->stopStaffId);
                    $this->verifyStaffIsStop($request->stopStaffId);
                }
                // 启用用户时校验 当前用户是否为停用状态
                if($request->startStaffId){
                    $this->verifyStaffIsExist($request->startStaffId);
                    $this->verifyStaffIsStart($request->startStaffId);
                    // 检验菜单是否存在
                    $menuIds = $request['menu_ids'];
                    if($menuIds) {
                        foreach ($menuIds as $menuId) {
                            $this->verifyAuthMenuIsExists($menuId);
                        }
                    }
                }
                // 批量删除员工时 验证员工是否存在
                if(isset($request['staff_ids']) && $request['staff_ids']){
                    foreach($request['staff_ids'] as $staffId){
                        $this->verifyStaffIsExist($staffId);
                    }
                }
                break;
            default:
                break;
        }

        return $next($request);
    }

    /**
     * 校验当前公司下 登录名称是否存在
     * @param $companyId
     * @param $loginAccount
     */
    private function verifyLoginAccountIsExist($companyId, $loginAccount){

        $isExist = $this->_staffModel->isExistByCondition([
            'company_id' => $companyId,
            'staff_login_account' => $loginAccount,
            'status' => BaseConsts::STATUS_NORMAL,
        ]);

        if($isExist){
            throw new HttpResponseException( ResponseFunc::returnJson(
                'error',
                null,
                '当前登录账号已存在',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                
            ));
        }

    }

    /**
     * 检验当前公司是否存在
     * @param $companyId
     */
    private function verifyCompanyIsExist($companyId){
        $isExist = $this->_companyModel->isExistByCondition([
            'company_id' => $companyId,
            'status' => BaseConsts::STATUS_NORMAL,
        ]);

        if(!$isExist){
            throw new HttpResponseException( ResponseFunc::returnJson(
                'error',
                null,
                '当前公司不存在',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                
            ));
        }
    }

    /**
     * 校验当前部门是否存在
     * @param $companyId
     * @param $departmentId
     */
    private function verifyDepartmentIsExist($companyId,$departmentId){
        $isExist = $this->_departmentModel->isExistByCondition([
            'department_id' => $departmentId,
            'company_id' => $companyId,
            'status' => BaseConsts::STATUS_NORMAL,
        ]);
        if(!$isExist){
            throw new HttpResponseException( ResponseFunc::returnJson(
                'error',
                null,
                $departmentId.'部门不存在',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                
            ));
        }

    }

    /**
     * 校验职位是否存在
     * @param $departmentId
     * @param $positionId
     */
    private function verifyPositionIsExist($departmentId,$positionId){
        $isExist = $this->_positionModel->isExistByCondition([
            'department_id' => $departmentId,
            'position_id' => $positionId,
            'status' => BaseConsts::STATUS_NORMAL,
        ]);
        if(!$isExist){
            throw new HttpResponseException( ResponseFunc::returnJson(
                'error',
                null,
                $positionId.'职位不存在',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                
            ));
        }
    }

    /**
     * 校验职位是否能修改
     * @param $staffDepartmentId
     */
    private function verifyStaffDepartmentIsExist($staffId,$staffDepartmentId){
        $isExist = $this->_staffDepartmentModel->isExistByCondition(
            [
                'staff_id' => $staffId,
                'staff_department_id' => $staffDepartmentId
            ]
        );
        if(!$isExist){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '职位参数错误',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                
            ));
        }

    }

    /**
     * 校验当前用户是否已经拥有这个部门了
     * @param $staffId
     * @param $departmentId
     */
    private function verifyStaffDepartmentHasStaffIsExist($staffId,$departmentId){
        $isExist = $this->_staffDepartmentModel->isExistByCondition(
            [
                'staff_id' => $staffId,
                'department_id' => $departmentId
            ]
        );
        if($isExist){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '当前用户已经属于这个部门',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                
            ));
        }

    }

    /**
     * 校验职位是否存在
     * @param $staffId
     */
    private function verifyStaffIsExist($staffId){
        $isExist = $this->_staffModel->isExistByCondition(
            [
                'staff_id' => $staffId,
                'status' => BaseConsts::STATUS_NORMAL
            ]
        );
        if(!$isExist){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                $staffId.'用户不存在或已删除',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                
            ));
        }
    }

    /**
     * 验证用户是否能停用
     * @param $staffId
     */
    private function verifyStaffIsStop($staffId){

        $isExist = $this->_staffModel->isExistByCondition(
            [
                'staff_id' => $staffId,
                'staff_status' => BaseConsts::STATUS_START
            ]
        );
        if(!$isExist){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '用户不存在或已停用',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                
            ));
        }
    }

    /**
     * 验证用户是否能启用
     * @param $staffId
     */
    private function verifyStaffIsStart($staffId){
        $isExist = $this->_staffModel->isExistByCondition(
            [
                'staff_id' => $staffId,
                'staff_status' => BaseConsts::STATUS_STOP
            ]
        );
        if(!$isExist){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                null,
                '用户不存在或已启用',
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
                
            ));
        }
    }


    /**
     * 检验菜单是否存在
     * @param $menuId
     */
    private function verifyAuthMenuIsExists($menuId){
        $isExist = $this->_authMenuModel->isExistByCondition(
            [
                'menu_id' =>$menuId
            ]
        );
        if(!$isExist){
            throw new HttpResponseException( ResponseFunc::returnJson(
                'error',
                null,
                "当前菜单不存在",
                ResponseStatusConsts::OK_200_RESPONSE_STATUS,
            ));
        }
    }

    private function verifyAuthBasic($auths){
        $staffInfo = TokenFuc::getCurrentStaffInfo();
        foreach($auths as $auth){
            // 校验当前权限是否存在
           $isExist =  $this->_authModel->isExistByCondition([
                'auth_id'=>$auth['auth_id'],
                'company_id' => $staffInfo['company_id'],
                'auth_type'=>$auth['auth_type']
           ]);
           if(!$isExist){
               throw new HttpResponseException( ResponseFunc::returnJson(
                   'error',
                   null,
                   "权限".$auth['auth_id']."不存在",
                   ResponseStatusConsts::OK_200_RESPONSE_STATUS,
               ));
           }
        }
    }

}